//
// Created by 陈坚 on 2023/3/22.
//

#ifndef KVSTORESIMPLE_KVSTORE_H
#define KVSTORESIMPLE_KVSTORE_H

#include <malloc.h>
#include <string>
#include <unordered_map>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include "ProtoBuf.h"

#define DEFAULT_KVSTORE_ID "default.kvstore"

static std::string g_rootDir;

class KVStore{
public:
    KVStore(const char *kvstoreID);
    static void initializeKVStore(const char *path);
    static KVStore* defaultKVStore();
    static KVStore* kvStoreWithID(const char* id);
    void putInt(const std::string& key,int32_t value);
    int32_t getInt(const std::string& key,int32_t defaultValue);

    void putString(const std::string& key,const char * value);
    const char * getString(const std::string& key);

    void putDouble(const std::string& key,double_t value);
    double_t getDouble(const std::string& key,double_t defaultValue);

    void putBoolean(const std::string& key,bool value);
    bool getBoolean(const std::string& key,bool defaultValue);

    void removeValueFromKey(const std::string& key);
    bool containsKey(const std::string& key);

    void putValue(const std::string& key,const void * value,const int len);
    void* getValue(const std::string& key);
    ProtoBuf* getValueProtoBuf(const std::string& key);

    void clear();
private:
    void loadFromFile();
    void zeroFillFile(int fd,int32_t startPos,int32_t size);
    void appendDataWithKey(std::string key,ProtoBuf* value);
public:
    //文件路径
    std::string m_path;
    //文件具柄
    int m_fd;
    //文件可写长度
    int32_t m_size;
    //内存中内容数据,mmap返回的虚拟地址
    int8_t *m_ptr;
    //已经使用的长度,也就是存放键值对总大小
    int32_t m_actualSize = 0;
    //hashmap
    std::unordered_map<std::string,ProtoBuf*> m_dic;
    //记录原始数据
    ProtoBuf *m_output;
};

#endif //KVSTORESIMPLE_KVSTORE_H
